#pragma once

#include "FVOperator.h"

/**
 * @file RungeKutta.h
 * @author xingyifan
 * @date 2022-08-31 22:51
 *
 * @description: 隐式-显式 RK 方法
 */

class IMEXRungeKutta
{
public:
    /**
     * @file RungeKutta.h
     * @author xingyifan
     * @date 2022-07-26 17:39
     *
     * @description: 初始化系数和权
     */

    IMEXRungeKutta() : AE_(6), AI_(6), b_(6), c_(6)
    {
        Real gamma = 0.25;

        // 初始化权和节点
        b_ = {0.15791629516167136, 0, 0.18675894052400077, 0.6805652953093346, -0.27524053099500667, gamma};
        c_ = {0, 0.5, 0.332, 0.62, 0.85, 1};

        // 显式系数
        AE_[1 * 6 + 0] = 2 * gamma;
        AE_[2 * 6 + 0] = 0.221776;
        AE_[2 * 6 + 1] = 0.110224;
        AE_[3 * 6 + 0] = -0.04884659515311857;
        AE_[3 * 6 + 1] = -0.17772065232640102;
        AE_[3 * 6 + 2] = 0.8465672474795197;
        AE_[4 * 6 + 0] = -0.15541685842491548;
        AE_[4 * 6 + 1] = -0.3567050098221991;
        AE_[4 * 6 + 2] = 1.0587258798684427;
        AE_[4 * 6 + 3] = 0.30339598837867193;
        AE_[5 * 6 + 0] = 0.2014243506726763;
        AE_[5 * 6 + 1] = 0.008742057842904185;
        AE_[5 * 6 + 2] = 0.15993995707168115;
        AE_[5 * 6 + 3] = 0.4038290605220775;
        AE_[5 * 6 + 4] = 0.22606457389066084;

        // 隐式系数
        AI_[1 * 6 + 0] = gamma;
        AI_[2 * 6 + 0] = 0.137776;
        AI_[2 * 6 + 1] = -0.055776;
        AI_[3 * 6 + 0] = 0.14463686602698217;
        AI_[3 * 6 + 1] = -0.22393190761334475;
        AI_[3 * 6 + 2] = 0.4492950415863626;
        AI_[4 * 6 + 0] = 0.09825878328356477;
        AI_[4 * 6 + 1] = -0.5915442428196704;
        AI_[4 * 6 + 2] = 0.8101210538282996;
        AI_[4 * 6 + 3] = 0.283164405707806;

        for (int i = 0; i < 5; i++)
        {
            AI_[5 * 6 + i] = b_[i];
        }
        for (int i = 1; i < 6; i++)
        {
            AI_[i * 6 + i] = gamma;
        }
    }

public:
    Matrix AE_, AI_; // 系数矩阵
    Vector b_;       // 加权
    Vector c_;       // 节点
};